package com.bhm.sdk.bhmlibrary.crash;

import android.os.Handler;
import android.os.Looper;

import com.bhm.sdk.bhmlibrary.interfaces.ExceptionHandler;

public final class Cockroach {

	private Cockroach() {

	}

	private static ExceptionHandler sExceptionHandler;
	private static Thread.UncaughtExceptionHandler sUncaughtExceptionHandler;
	private static boolean sInstalled = false;//标记位，避免重复安装卸载

	/**
	 * 当主线程或子线程抛出异常时会调用exceptionHandler.handlerException(Thread thread, Throwable throwable)
	 * <p>
	 * exceptionHandler.handlerException可能运行在非UI线程中。
	 * <p>
	 * 若设置了Thread.setDefaultUncaughtExceptionHandler则可能无法捕获子线程异常。
	 *
	 * @param exceptionHandler
	 */
	public static synchronized void install(ExceptionHandler exceptionHandler) {
		if (sInstalled) {
			return;
		}
		sInstalled = true;
		sExceptionHandler = exceptionHandler;

		new Handler(Looper.getMainLooper()).post(new Runnable() {
			@Override
			public void run() {

				while (true) {
					try {
						Looper.loop();
					} catch (Throwable e) {
						if (e instanceof QuitCockroachException) {
							return;
						}
						if (sExceptionHandler != null) {
							sExceptionHandler.handlerException(Looper.getMainLooper().getThread(), e);
						}
					}
				}
			}
		});

		sUncaughtExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
		Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
			@Override
			public void uncaughtException(Thread t, Throwable e) {
				if (sExceptionHandler != null) {
					sExceptionHandler.handlerException(t, e);
				}
			}
		});

	}

	public static synchronized void uninstall() {
		if (!sInstalled) {
			return;
		}
		sInstalled = false;
		sExceptionHandler = null;
		//卸载后恢复默认的异常处理逻辑，否则主线程再次抛出异常后将导致ANR，并且无法捕获到异常位置
		Thread.setDefaultUncaughtExceptionHandler(sUncaughtExceptionHandler);
		new Handler(Looper.getMainLooper()).post(new Runnable() {
			@Override
			public void run() {
				throw new QuitCockroachException("Quit Cockroach.....");//主线程抛出异常，迫使 while (true) {}结束
			}
		});

	}
}
